package com.bj58.wuxian.lucene.search;

import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.store.Directory;
import org.junit.Before;
import org.junit.Test;

import com.bj58.wuxian.lucene.constants.Constants;
import com.bj58.wuxian.lucene.utils.LuceneUtil;

public class Searcher{

	private Analyzer analyzer;
	private Directory directory;

	@Before
	public void init() throws IOException {
		analyzer = new StandardAnalyzer();

		// 在内存中 创建索引
		// directory = new RAMDirectory();
		// 在磁盘中创建索引
		directory = LuceneUtil.getDirectory("D:\\index");
	}
	
	// 创建索引
	@Test
	public void index() throws IOException {
		IndexWriter iwriter = LuceneUtil.getIndexWriter(directory, analyzer);
		Document doc = new Document();
		String text = "Lucene是apache软件基金会的一个子项目，是一个开放源代码的全文检索引擎工具包";
		doc.add(new Field("context", text, TextField.TYPE_STORED));
		iwriter.addDocument(doc);
		LuceneUtil.close(iwriter, directory);
	}


	// 搜索
	@Test
	public void search() throws IOException, ParseException {
		// 打开索引字典

		DirectoryReader ireader = LuceneUtil.getDirectoryReader(directory);
		IndexSearcher isearcher = LuceneUtil.getIndexSearcher(ireader);
		QueryParser parser = new QueryParser("desc", analyzer);
		Query query = parser.parse("三国演义");
		ScoreDoc[] hits = isearcher.search(query, 10).scoreDocs;

		for (int i = 0; i < hits.length; i++) {
			Document hitDoc = isearcher.doc(hits[i].doc);
			System.out.println("id： " + hitDoc.get("id") + "  title:" + hitDoc.get("title") + "   author:"
					+ hitDoc.get("author") + "   price:" + hitDoc.get("price") + "   desc:" + hitDoc.get("desc")
					+ "  得分:" + hits[i].score);
		}
		LuceneUtil.close(ireader, directory);
	}

	// 搜索排序
	@Test
	public void searchBySort() throws IOException, ParseException {
		// 打开索引字典
		DirectoryReader ireader = LuceneUtil.getDirectoryReader(directory);
		IndexSearcher isearcher = LuceneUtil.getIndexSearcher(ireader);

		QueryParser parser = new QueryParser("desc", analyzer);
		Query query = parser.parse("三国演义");

		ScoreDoc[] hits = isearcher.search(query, 10, new Sort(new SortField("price", Type.INT, true))).scoreDocs;

		for (int i = 0; i < hits.length; i++) {
			Document hitDoc = isearcher.doc(hits[i].doc);
			System.out.println("id： " + hitDoc.get("id") + "  title:" + hitDoc.get("title") + "   author:"
					+ hitDoc.get("author") + "   price:" + hitDoc.get("price") + "   desc:" + hitDoc.get("desc")
					+ "  得分:" + hits[i].score);
		}
		LuceneUtil.close(ireader, directory);
	}

	@Test
	public void testSearchByPage() {
		try {
			searchByPage("desc", "三国演义", 3);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	// 搜索分页
	public void searchByPage(String fieldName, String value, int pageNum) throws IOException, ParseException {
		// 打开索引字典
		DirectoryReader ireader = DirectoryReader.open(directory);
		IndexSearcher isearcher = new IndexSearcher(ireader);

		QueryParser parser = new QueryParser(fieldName, analyzer);
		Query query = parser.parse(value);

		Sort sort = new Sort(new SortField("price", Type.INT, true));

		// 计算需要几条
		int start = (pageNum - 1) * Constants.PAGE_SIZE;

		ScoreDoc[] hits = null;
		if (start == 0) {
			hits = isearcher.search(query, Constants.PAGE_SIZE,
					new Sort(new SortField("price", Type.INT, true))).scoreDocs;

		} else {
			ScoreDoc[] hitsPres = isearcher.search(query, start, sort).scoreDocs;
			ScoreDoc preHit = hitsPres[start - 1];
			hits = isearcher.searchAfter(preHit, query, Constants.PAGE_SIZE, sort).scoreDocs;
		}

		for (int i = 0; i < hits.length; i++) {
			Document hitDoc = isearcher.doc(hits[i].doc);
			System.out.println("id： " + hitDoc.get("id") + "  title:" + hitDoc.get("title") + "   author:"
					+ hitDoc.get("author") + "   price:" + hitDoc.get("price") + "   desc:" + hitDoc.get("desc"));
		}
		ireader.close();
		directory.close();
	}

}
